#include "OmegaMesh.h"

OmegaMesh::OmegaMesh(){

}
void OmegaMesh::loadMesh(const char* fname)
{
	
	std::ifstream::pos_type size;
	char * memblock;

	std::ifstream file (fname, std::ios::in|std::ios::binary|std::ios::ate);
	if (file.is_open())
	{
		size = file.tellg();
		memblock = new char [(int)size];
		file.seekg (0, std::ios::beg);
		file.read (memblock, size);
		file.close();
	}
	else
	{	
		/*LPCSTR err = fname;
		MessageBox(NULL, "Unable to open file...", err, MB_OK | MB_ICONERROR);*/
		return;
	}
	
	std::stringstream strstream(memblock); 	
	std::string fptr;
	strstream >> fptr;
	if(fptr.compare(0,9,"alphamesh")!=0){
		std::cerr << "This is an invalid mesh, it won't be included in the model" << std::endl;
		/*LPCSTR err = fname;
		MessageBox(NULL, "This is an invalid mesh, it won't be included in the model", err, MB_OK | MB_ICONERROR);*/
		return;
	}else{
		fptr = fptr.substr(9,14);
//		std::cout << "Mesh Version '" << fptr.c_str() << "' This *should* be fine." << std::endl;
	}

	strstream >> this->numVerts;
	verts = new vec3[numVerts];
	for (int i=0;i<numVerts;i++){
		strstream>>verts[i][0]>>verts[i][1]>>verts[i][2];
	}
	strstream>>numNormals;
	norms = new vec3[numVerts];
	for (int i=0;i<numVerts;i++){
		strstream>>norms[i][0]>>norms[i][1]>>norms[i][2];
	}
	strstream>>numTexCd;
	texcd = new vec2[numTexCd];
	for (int i=0;i<numTexCd;i++){
		strstream>>texcd[i][0]>>texcd[i][1];
	}
	strstream>>numTris;
	tris = new GLuint[numTris];
	texTris = new GLuint[numTris];
	for (int i=0;i<numTris;i++){
		strstream>>tris[i]>>texTris[i];
	}
	// Insert code to fix triangles here
	//
	//
	//

	// Load the Default Shader
	//s = new Shader("..\\SDLFramework\\Shaders\\ADS.vert","..\\SDLFramework\\Shaders\\ADSAdv.frag");
	//mat = new Material(WHITE);
	enabled = true;

	GLuint tris[6] = {0,1,2,1,2,3};

	GLfloat verts[4][3] = {    
		{  -10.0, 0.0, -10.0  }, 
		{  -10.0, 0.0, 10.0 }, 
		{  10.0, 0.0, -10.0 }, 
		{ 10.0,  0.0, 10.0 }}; 

	GLfloat norms[4][3] = {
		{  0.0,  1.0,  0.0  }, 
		{  0.0,  1.0,  0.0  }, 
		{  0.0,  1.0,  0.0  }, 
		{  0.0,  1.0,  0.0  } }; 
	GLfloat texcd[4][2] = {
		{ 0.0 , 0.0 },
		{ 1.0 , 0.0 },
		{ 0.0 , 1.0 },
		{ 1.0 , 1.0 }};

	glGenVertexArrays(1,&vao);
	glBindVertexArray(vao);
	
	glGenBuffers(4,vbo);
	glBindBuffer(GL_ARRAY_BUFFER,vbo[0]);
	glBufferData(GL_ARRAY_BUFFER,numVerts *3*sizeof(GLfloat),this->verts,GL_STATIC_DRAW);
	glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,0,0);
	glEnableVertexAttribArray(0);

	glBindBuffer(GL_ARRAY_BUFFER,vbo[1]);
	glBufferData(GL_ARRAY_BUFFER,numVerts*3*sizeof(GLfloat),this->norms,GL_STATIC_DRAW);
	glVertexAttribPointer(1,3,GL_FLOAT,GL_FALSE,0,0);
	glEnableVertexAttribArray(1);

	glBindBuffer(GL_ARRAY_BUFFER,vbo[2]);
	glBufferData(GL_ARRAY_BUFFER,numTexCd*2*sizeof(GLfloat),this->texcd,GL_STATIC_DRAW);
	glVertexAttribPointer(2,2,GL_FLOAT,GL_FALSE,0,0);
	glEnableVertexAttribArray(2);

	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,vbo[3]);
	/////////////////////////////////////////////////////////
	// NOTE: Access Violation (0x0000005) has occured when:
	//
	//	1.	You access more triangles than you have in the mesh.
	//		this can happen if you DONT load in enough tris.
	//		seems to be happening the most often.
	//
	glBufferData(GL_ELEMENT_ARRAY_BUFFER,this->numTris * sizeof(GLuint),this->tris,GL_STATIC_DRAW);

}

void OmegaMesh::display(/*AlphaMatrix* mvm,AlphaMatrix* proj,float* lightPos*/){
	if(enabled){
		//s->activate();

		//int ui = glGetUniformLocation(s->getProgram(),"MVM");
		//glUniformMatrix4fv(ui,1,GL_FALSE,mvm->returnPtr());

		//ui = glGetUniformLocation(s->getProgram(),"PROJ");
		//glUniformMatrix4fv(ui,1,GL_FALSE,proj->returnPtr());
		//		
		//ui = glGetUniformLocation(s->getProgram(),"tu0");
		//glUniform1i(ui,0);
		//
		//ui = glGetUniformLocation(s->getProgram(),"tu1");
		//glUniform1i(ui,1);
		//
		//ui = glGetUniformLocation(s->getProgram(),"tu2");
		//glUniform1i(ui,2);
 
		//ui = glGetUniformLocation(s->getProgram(),"tu3");
		//glUniform1i(ui,3);
				
		/*ui = glGetUniformLocation(s->getProgram(), "material.ambient");
		glUniform4fv(ui,1,mat->a);
		
		ui = glGetUniformLocation(s->getProgram(), "material.diffuse");
		glUniform4fv(ui, 1,mat->d);
	
		ui = glGetUniformLocation(s->getProgram(), "material.specular");
		glUniform4fv(ui, 1, mat->s);
	
		ui = glGetUniformLocation(s->getProgram(), "material.shininess");
		glUniform1f(ui, mat->sh);*/
	/*	
		ui = glGetUniformLocation(s->getProgram(),"lightPosition");
		glUniform4fv(ui,1,lightPos);*/

		glBindVertexArray(this->vao);
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,vbo[3]);
		glDrawElements(GL_TRIANGLES,this->numTris*3,GL_UNSIGNED_INT,0);
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0);
	}
}

OmegaMesh::~OmegaMesh(void)
{
	delete [] verts;
	delete [] norms;
	delete [] texcd;
	delete [] tris;
	delete [] texTris;

}
